// 订单客户枚举类型
const enum OrderType {
    client500 = 1,
    client200,
    clientNormal
}
// 初版处理订单逻辑函数
function handleOrder(orderType: number, hasPay: boolean, stock: number) {
    if (orderType === OrderType.client500) {
        if (hasPay) {
            console.log('已经支付500元定金，额外获得200元优惠券');
        } else {
            if (stock > 0) {
                console.log('拥有库存，购买成功')
            } else {
                console.log('已售罄');
            }
        }
    } else if (orderType === OrderType.client200) {
        if (hasPay) {
            console.log('已经支付200元定金，额外获得50元优惠券');
        } else {
            if (stock > 0) {
                console.log('拥有库存，购买成功')
            } else {
                console.log('已售罄');
            }
        }
    } else if (orderType === OrderType.clientNormal) {
        if (stock > 0) {
            console.log('拥有库存，购买成功')
        } else {
            console.log('已售罄');
        }
    }
}

// 测试用例
handleOrder(1, true, 500);//已经支付500元定金，额外获得200元优惠券
handleOrder(1, true, 0);//已经支付500元定金，额外获得200元优惠券
handleOrder(2, false, 100);//拥有库存，购买成功


// 函数组合模式重构

// 处理500元定金用户的逻辑
function handleOrder500(orderType: number, hasPay: boolean, stock: number) {
    if (orderType === OrderType.client500 && hasPay === true) {
        console.log('已经支付500元定金，额外获得200元优惠券');
    } else {
        handleOrder200(orderType, hasPay, stock);// 把请求转移
    }
}
// 处理200元定金用户的逻辑
function handleOrder200(orderType: number, hasPay: boolean, stock: number) {
    if (orderType === OrderType.client200 && hasPay === true) {
        console.log('已经支付200元定金，额外获得50元优惠券');
    } else {
        handleOrderNormal(orderType, hasPay, stock);// 把请求转移
    }
}

// 处理未支付定金用户的逻辑
function handleOrderNormal(orderType: number, hasPay: boolean, stock: number) {
    if (stock > 0) {
        console.log('拥有库存，购买成功')
    } else {
        console.log('已售罄');
    }
}

// 测试用例
handleOrder500(1, true, 500); // 输出：500 元定金预购, 得到 100 优惠券
handleOrder500(1, false, 500); // 输出：拥有库存，购买成功
handleOrder500(2, true, 500); // 输出：200 元定金预购, 得到 50 优惠券
handleOrder500(3, false, 500); // 输出：拥有库存，购买成功
handleOrder500(3, false, 0); // 输出：已售罄


// 基于职责链模式进行重构
const PASS_MESSAGE = '__NEXT__';// 表示向后传递的签名
// 职责链节点：处理500元定金用户的逻辑
function order500(orderType: number, hasPay: boolean, stock: number) {
    if (orderType === OrderType.client500 && hasPay === true) {
        console.log('已经支付500元定金，额外获得200元优惠券');
    } else {
        return PASS_MESSAGE;
    }
}
// 职责链节点：处理200元定金用户的逻辑
function order200(orderType: number, hasPay: boolean, stock: number) {
    if (orderType === OrderType.client200 && hasPay === true) {
        console.log('已经支付200元定金，额外获得50元优惠券');
    } else {
        return PASS_MESSAGE;
    }
}
// 职责链节点：处理未支付定金用户的逻辑
function orderNormal(orderType: number, hasPay: boolean, stock: number) {
    if (stock > 0) {
        console.log('拥有库存，购买成功')
    } else {
        console.log('已售罄');
    }
}

// 职责链类
class ObligationChain {
    func: Function;
    nextNode: ObligationChain | null;// 后继节点
    static PASS_MESSAGE = PASS_MESSAGE;
    // 构造函数
    constructor(fn: Function) {
        this.func = fn;
        this.nextNode = null;
    }
    // 设置后继函数
    setNextNode(successor: ObligationChain) {
        this.nextNode = successor;
        return this.nextNode;
    }
    // 传递请求函数
    passRequeset(this: ObligationChain, ...params: any[]) {
        const res = this.func(...params);
        if (res === ObligationChain.PASS_MESSAGE) {// 如果需要传递请求
            if (this.nextNode) {
                this.nextNode.passRequeset.apply(this.nextNode, params);
            } else {
                return null;
            }
        } else {
            return res;
        }
    }
}


// 测试用例
const chain500 = new ObligationChain(order500);// 传入职责节点形成职责链实例
const chain200 = new ObligationChain(order200);
const chainNormal = new ObligationChain(orderNormal);
chain500.setNextNode(chain200);// 传入职责链实例
chain200.setNextNode(chainNormal);
// 测试用例
chain500.passRequeset(3, false, 500);// 从500开始传递
chain500.passRequeset(1, true, 500);
chain500.passRequeset(2, true, 500);


// 异步职责链类
class AsyncObligationChain extends ObligationChain {
    constructor(fn: Function) {
        super(fn);
    }
    // 手动设置一个请求方法,只负责向下游发送请求
    manualPassRequest(...params: any[]) {
        if (this.nextNode) {
            return this.nextNode.passRequeset.apply(this.nextNode, params);// 注意这里的this指向
        }
    }
}

// 测试用例
// 声明三个异步函数职责链节点和一个同步函数节点
const asyncFn1 = new AsyncObligationChain(function (this: AsyncObligationChain) {
    setTimeout(() => {
        console.log(asyncFn1, 1);
        this.manualPassRequest();
    }, 2000);
});
const asyncFn2 = new AsyncObligationChain(function (this: AsyncObligationChain) {
    setTimeout(() => {
        console.log(asyncFn2, 2);
        this.manualPassRequest();
    }, 2000);
});
const syncFn1 = new AsyncObligationChain(function (this: AsyncObligationChain) {
    console.log(syncFn1, 3);
    return PASS_MESSAGE;
});
const asyncFn3 = new AsyncObligationChain(function (this: AsyncObligationChain) {
    setTimeout(() => {
        console.log(asyncFn3, 4);
        this.manualPassRequest();
    }, 2000);
});
// 确定职责链关系
asyncFn1.setNextNode(asyncFn2).setNextNode(syncFn1).setNextNode(asyncFn3);
asyncFn1.passRequeset();

